/*
 * Copyright (C) 2011 CrystalRange
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.crystalrange.enterprise.web;

import com.googlecode.genericdao.search.Filter;
import com.googlecode.genericdao.search.Search;
import org.apache.commons.lang3.StringUtils;
import org.crystalrange.enterprise.model.StorageType;
import org.crystalrange.enterprise.model.WarehouseNumber;
import org.crystalrange.searching.SearchOperatorListitemRenderer;
import org.crystalrange.searching.SearchOperators;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
import org.zkoss.zul.Bandbox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

public class StorageSectionSearchController extends GenericForwardComposer {

    protected Listbox sortOperatorName;
    protected Listbox sortOperatorWarehouseNumber;
    protected Listbox sortOperatorStorageType;
    protected Listbox sortOperatorDescription;
    protected Textbox textboxName;
    protected Bandbox bandboxWarehouseNumber;
    protected Bandbox bandboxStorageType;
    protected Textbox textboxDescription;
    protected WarehouseNumber selectedWarehouseNumber;
    protected StorageType selectedStorageType;
    protected Search searchStorageSection;
    protected AnnotateDataBinder binder;

    public Search getSearchStorageSection() {
        return this.searchStorageSection;
    }

    public WarehouseNumber getSelectedWarehouseNumber() {
        return this.selectedWarehouseNumber;
    }

    public void setSelectedWarehouseNumber(WarehouseNumber selectedWarehouseNumber) {
        this.selectedWarehouseNumber = selectedWarehouseNumber;
    }

    public StorageType getSelectedStorageType() {
        return this.selectedStorageType;
    }

    public void setSelectedStorageType(StorageType selectedStorageType) {
        this.selectedStorageType = selectedStorageType;
    }

    @Override
    public void doAfterCompose(Component component) throws Exception {
        super.doAfterCompose(component);

        this.sortOperatorName.setModel(new ListModelList(SearchOperators.getAllOperators()));
        this.sortOperatorName.setItemRenderer(new SearchOperatorListitemRenderer());

        this.sortOperatorWarehouseNumber.setModel(new ListModelList(SearchOperators.getAllOperators()));
        this.sortOperatorWarehouseNumber.setItemRenderer(new SearchOperatorListitemRenderer());

        this.sortOperatorStorageType.setModel(new ListModelList(SearchOperators.getAllOperators()));
        this.sortOperatorStorageType.setItemRenderer(new SearchOperatorListitemRenderer());

        this.sortOperatorDescription.setModel(new ListModelList(SearchOperators.getAllOperators()));
        this.sortOperatorDescription.setItemRenderer(new SearchOperatorListitemRenderer());

        this.searchStorageSection = (Search) this.execution.getAttribute("searchStorageSection");

        if (this.searchStorageSection != null) {
            for (Filter filter : this.searchStorageSection.getFilters()) {
                if (filter.getProperty().equals("name")) {
                    this.restoreOperator(this.sortOperatorName, filter);
                    this.textboxName.setValue(filter.getValue().toString());
                } else if (filter.getProperty().equals("warehouseNumber")) {
                    this.restoreOperator(this.sortOperatorWarehouseNumber, filter);
                    this.selectedWarehouseNumber = (WarehouseNumber) filter.getValue();
                } else if (filter.getProperty().equals("storageType")) {
                    this.restoreOperator(this.sortOperatorStorageType, filter);
                    this.selectedStorageType = (StorageType) filter.getValue();
                } else if (filter.getProperty().equals("description")) {
                    this.restoreOperator(this.sortOperatorDescription, filter);
                    this.textboxDescription.setValue(filter.getValue().toString());
                }
            }
        }

        component.setAttribute("controller", this);
    }

    private void restoreOperator(Listbox listbox, Filter filter) {
        if (filter.getOperator() == Filter.OP_EQUAL) {
            listbox.setSelectedIndex(1);
        } else if (filter.getOperator() == Filter.OP_NOT_EQUAL) {
            listbox.setSelectedIndex(2);
        } else if (filter.getOperator() == Filter.OP_LESS_THAN) {
            listbox.setSelectedIndex(3);
        } else if (filter.getOperator() == Filter.OP_GREATER_THAN) {
            listbox.setSelectedIndex(4);
        } else if (filter.getOperator() == Filter.OP_LESS_OR_EQUAL) {
            listbox.setSelectedIndex(5);
        } else if (filter.getOperator() == Filter.OP_GREATER_OR_EQUAL) {
            listbox.setSelectedIndex(6);
        } else if (filter.getOperator() == Filter.OP_ILIKE) {
            listbox.setSelectedIndex(7);
        }
    }

    public void onClick$buttonOk(Event event) throws Exception {
        this.searchStorageSection.getFilters().clear();

        if (StringUtils.isNotEmpty(this.textboxName.getText())) {
            Listitem item = this.sortOperatorName.getSelectedItem();
            if (item != null) {
                SearchOperators searchOperator = (SearchOperators) item.getValue();
                if (searchOperator.getSearchOperatorId() != -1) {
                    this.searchStorageSection.addFilter(new Filter("name", this.textboxName.getValue(), searchOperator.getSearchOperatorId()));
                }
            }
        }

        if (StringUtils.isNotEmpty(this.bandboxWarehouseNumber.getText())) {
            Listitem item = this.sortOperatorWarehouseNumber.getSelectedItem();
            if (item != null) {
                SearchOperators searchOperator = (SearchOperators) item.getValue();
                if (searchOperator.getSearchOperatorId() != -1) {
                    this.searchStorageSection.addFilter(new Filter("warehouseNumber", this.selectedWarehouseNumber, searchOperator.getSearchOperatorId()));
                }
            }
        }

        if (StringUtils.isNotEmpty(this.bandboxStorageType.getText())) {
            Listitem item = this.sortOperatorStorageType.getSelectedItem();
            if (item != null) {
                SearchOperators searchOperator = (SearchOperators) item.getValue();
                if (searchOperator.getSearchOperatorId() != -1) {
                    this.searchStorageSection.addFilter(new Filter("storageType", this.selectedStorageType, searchOperator.getSearchOperatorId()));
                }
            }
        }

        if (StringUtils.isNotEmpty(this.textboxDescription.getText())) {
            Listitem item = this.sortOperatorDescription.getSelectedItem();
            if (item != null) {
                SearchOperators searchOperator = (SearchOperators) item.getValue();
                if (searchOperator.getSearchOperatorId() != -1) {
                    this.searchStorageSection.addFilter(new Filter("description", this.textboxDescription.getValue(), searchOperator.getSearchOperatorId()));
                }
            }
        }

        this.execution.setAttribute("searchStorageSection", this.searchStorageSection);
        this.execution.setAttribute("result", "ok");
        this.self.detach();
    }

    public void onOpen$bandboxWarehouseNumber(Event event) throws Exception {
        Window window = (Window) this.execution.createComponents("~./zul/html/warehouseNumberSelect.zul", null, null);
        window.setParent(self);
        window.doModal();

        if (this.execution.getAttribute("result") == "ok") {
            this.selectedWarehouseNumber = (WarehouseNumber) this.execution.getAttribute("selectedWarehouseNumber");
        }

        this.binder.loadAll();
    }

    public void onOpen$bandboxStorageType(Event event) throws Exception {
        Window window = (Window) this.execution.createComponents("~./zul/html/storageTypeSelect.zul", null, null);
        window.setParent(self);
        window.doModal();

        if (this.execution.getAttribute("result") == "ok") {
            this.selectedStorageType = (StorageType) this.execution.getAttribute("selectedStorageType");
        }

        this.binder.loadAll();
    }

    public void onClick$buttonCancel(Event event) throws Exception {
        this.execution.setAttribute("searchStorageSection", null);
        this.execution.setAttribute("result", "cancel");
        this.self.detach();
    }
}
